//
// Created by xzl on 2018/2/21.
//

#ifndef FTPDELEGATE_H
#define FTPDELEGATE_H

#include <string>
#include <functional>
#include <mutex>

using namespace std;

class FtpDelegate {
public:
    FtpDelegate(){}
    virtual ~FtpDelegate(){}
    virtual void onStart(int total,int offset,int fileTime) = 0; //开始下载
    virtual void onCancel() = 0;//被取消
    virtual void onProgress(char *data,int size) = 0;//下载中...
    virtual void onComplete() = 0;//下载成功
    virtual void onFailed(int err_code,const string &err_msg) = 0;//下载中途失败
};

class FtpCallBack : public FtpDelegate
{
public:
    FtpCallBack(){}
    ~FtpCallBack(){}

    void onStart(int total,int offset,int fileTime) override{
        lock_guard<recursive_mutex> lck(_mtx);
        if(_onStart){
            if(!_onStart(total,offset,fileTime)){
                _onStart = nullptr;
            }
        }
    }
    void onCancel() override{
        lock_guard<recursive_mutex> lck(_mtx);
        if(_onCancel){
            if(!_onCancel()) {
                _onCancel = nullptr;
            }
        }
    }
    void onProgress(char *data,int size) override{
        lock_guard<recursive_mutex> lck(_mtx);
        if(_onProgress){
            if(!_onProgress(data,size)){
                _onProgress = nullptr;
            }
        }
    }
    void onComplete() override{
        lock_guard<recursive_mutex> lck(_mtx);
        if(_onComplete){
            if(!_onComplete()){
                _onComplete = nullptr;
            }
        }
    }
    void onFailed(int err_code,const string &err_msg) override{
        lock_guard<recursive_mutex> lck(_mtx);
        if(_onFailed){
            if(!_onFailed(err_code,err_msg)){
                _onFailed = nullptr;
            }
        }
    }
    void clear(){
        lock_guard<recursive_mutex> lck(_mtx);
        _onStart = nullptr;
        _onCancel = nullptr;
        _onProgress = nullptr;
        _onComplete = nullptr;
        _onFailed = nullptr;
    }
    template <typename onStart,typename onCancel,typename onProgress,typename onComplete,typename onFailed>
    void setCallBack(const onStart &a,const onCancel &b,const onProgress &c ,const onComplete &d,const onFailed &e){
        lock_guard<recursive_mutex> lck(_mtx);
        _onStart = a;
        _onCancel = b;
        _onProgress = c;
        _onComplete = d;
        _onFailed = e;
    }
private:
    recursive_mutex _mtx;
    function<bool(int total,int offset,int fileTime)> _onStart;
    function<bool()> _onCancel;
    function<bool(char *data,int size)> _onProgress;
    function<bool()> _onComplete;
    function<bool(int err_code,const string &err_msg)> _onFailed;
};

#endif //FTPDELEGATE_H
